#ifndef _MODPLAYER_H_
#define _MODPLAYER_H_

class CFile;

class CModPlayer
{
private:
	static CModPlayer __this;
	static u8 m_channelPan[8];
	
	
	typedef struct
	{
		u16	mod_sig;		//should be "SM"
		u8	mod_len;		//song length (in patterns)
		u8	mod_patterns;	//number of patterns
		u8	mod_channels;	//number of channels, 4, 6 or 8
		u8	mod_samples;	//number of samples, 15 or 31
	}TModHeader;

	typedef struct  
	{
		u32 sample_offset;			//position in sample data
		u16	sample_len;				//length of sample (in words)
		u16	sample_repeatOffset;	//where to start repeating (in words)
		u16	sample_repeatLen;		//how much to repeat (in words)
		u8	sample_volume;			//volume of sample, 0..64
		u8	sample_finetune;		//fine-tuning
	}TModSample;

	typedef struct 
	{
		u16	pat_sampleID:5;			//sample ID
		u16	pat_sampleNote:7;		//index of the note from amiga table
		u16	pat_effect:4;			//effect number
		u8	pat_paramX;				//effect param x	stupid ARM data alignment, can't declare paramX:4 and paramY:4
		u8	pat_paramY;				//effect param y
	}TModPattern;

	
	//loading vars
	TModHeader mod_header;
	TModSample mod_samples[31];
	TModPattern *mod_patterns;
	s8 *mod_sampleData;
	u8 mod_order[128];
	
	
	//playing vars
	u32 m_tick;
	u32 m_speed;
	u32 m_row;
	u32 m_pattern;
	
	u8 	m_chInstrument[8];
	u8 	m_chVolume[8];
	u16	m_chFreq[8];
	
	
	u8 m_totalVolume;
	
	CModPlayer();
	void setTimer();
	
	
	void initSong();
	void updateTick();
	void updateRow();
	void updateEffect();
		
	void playNote(u8 sample, u16 freq, u8 volume, u8 channel);
	void setVolume(u8 channel, u8 volume);
	
	friend void CModPlayer_IRQ();
protected:
public:
	static CModPlayer *getInstance() { return &__this;}
	
	BOOL loadFile(CFile *f);
	void play();
	void stop();
};

#endif //_MODPLAYER_H_